﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.IO.Compression;

namespace ibba.src.norisk.Utils
{
    public class Compression
    {
        public byte[] Compress(object obj)
        {
            System.Runtime.Serialization.Formatters.Binary.BinaryFormatter _binaryFormatter;
            byte[] _buffer = null;

            try
            {
                using (System.IO.MemoryStream _stream = new System.IO.MemoryStream())
                {
                    _binaryFormatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();

                    _binaryFormatter.Serialize(_stream, obj);

                    _buffer = _stream.ToArray();
                }

                return Compress(_buffer);
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                _binaryFormatter = null;
                _buffer = null;
            }
        }

        public TResult Decompress<TResult>(byte[] buffer_)
        {
            System.Runtime.Serialization.Formatters.Binary.BinaryFormatter _binaryFormatter = null;
            object _objResult = null;

            try
            {
                using (System.IO.MemoryStream _stream = new System.IO.MemoryStream(Decompress(buffer_)))
                {
                    _binaryFormatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();

                    _objResult = _binaryFormatter.Deserialize(_stream);
                }

                return (TResult)_objResult;
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                buffer_ = null;
                _binaryFormatter = null;
                _objResult = null;
            }
        }

        public byte[] Compress(byte[] buffer_)
        {
            byte[] _compressedData = null;

            try
            {
                using (MemoryStream _memoryStream = new MemoryStream())
                {
                    using (GZipStream gZipStream = new GZipStream(_memoryStream, CompressionMode.Compress, true))
                    {
                        gZipStream.Write(buffer_, 0, buffer_.Length);
                    }

                    _compressedData = _memoryStream.ToArray();
                }

                return _compressedData;
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                buffer_ = null;
                _compressedData = null;
            }
        }

        public byte[] Decompress(byte[] buffer_)
        {
            byte[] _gZipBuffer = null;

            try
            {
                using (GZipStream _gZipStream = new GZipStream(new MemoryStream(buffer_), CompressionMode.Decompress))
                {
                    const int size = 4096;
                    _gZipBuffer = new byte[size];
                    using (MemoryStream _memoryStream = new MemoryStream())
                    {
                        int count = 0;
                        do
                        {
                            count = _gZipStream.Read(_gZipBuffer, 0, size);
                            if (count > 0)
                            {
                                _memoryStream.Write(_gZipBuffer, 0, count);
                            }
                        }
                        while (count > 0);

                        _gZipBuffer = _memoryStream.ToArray();
                    }
                }

                return _gZipBuffer;
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                buffer_ = null;
                _gZipBuffer = null;
            }
        }

        public string Compress(string text_)
        {
            return Convert.ToBase64String(Compress(Encoding.GetEncoding("iso-8859-1").GetBytes(text_)));
        }

        public string Decompress(string compressedText_)
        {
            return Encoding.GetEncoding("iso-8859-1").GetString(Decompress(Convert.FromBase64String(compressedText_)));
        }
    }
}
